using System;
using System.Linq;
using System.Text;
using HslCommunication.BasicFramework;
using HslCommunication.Core;
using HslCommunication.Serial;

namespace HslCommunication.Profinet.FATEK
{
	/// <summary>
	/// 台湾永宏公司的编程口协议，具体的地址信息请查阅api文档信息<br />
	/// The programming port protocol of Taiwan Yonghong company, please refer to the api document for specific address information
	/// </summary>
	/// <remarks>
	/// <inheritdoc cref="T:HslCommunication.Profinet.FATEK.FatekProgramOverTcp" path="remarks" />
	/// </remarks>
	public class FatekProgram : SerialDeviceBase
	{
		private byte station = 1;

		/// <inheritdoc cref="P:HslCommunication.Profinet.FATEK.FatekProgramOverTcp.Station" />
		public byte Station
		{
			get
			{
				return station;
			}
			set
			{
				station = value;
			}
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.FATEK.FatekProgramOverTcp.#ctor" />
		public FatekProgram()
		{
			base.ByteTransform = new RegularByteTransform();
			base.WordLength = 1;
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.FATEK.FatekProgramOverTcp.Read(System.String,System.UInt16)" />
		public override OperateResult<byte[]> Read(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = FatekProgramOverTcp.BuildReadCommand(station, address, length, isBool: false);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult);
			}
			OperateResult<byte[]> operateResult2 = ReadBase(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<byte[]>(operateResult2);
			}
			if (operateResult2.Content[0] != 2)
			{
				return new OperateResult<byte[]>(operateResult2.Content[0], "Read Faild:" + SoftBasic.ByteToHexString(operateResult2.Content, ' '));
			}
			if (operateResult2.Content[5] != 48)
			{
				return new OperateResult<byte[]>(operateResult2.Content[5], FatekProgramOverTcp.GetErrorDescriptionFromCode((char)operateResult2.Content[5]));
			}
			byte[] array = new byte[length * 2];
			for (int i = 0; i < array.Length / 2; i++)
			{
				ushort value = Convert.ToUInt16(Encoding.ASCII.GetString(operateResult2.Content, i * 4 + 6, 4), 16);
				BitConverter.GetBytes(value).CopyTo(array, i * 2);
			}
			return OperateResult.CreateSuccessResult(array);
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.FATEK.FatekProgramOverTcp.Write(System.String,System.Byte[])" />
		public override OperateResult Write(string address, byte[] value)
		{
			OperateResult<byte[]> operateResult = FatekProgramOverTcp.BuildWriteByteCommand(station, address, value);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult<byte[]> operateResult2 = ReadBase(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			if (operateResult2.Content[0] != 2)
			{
				return new OperateResult(operateResult2.Content[0], "Write Faild:" + SoftBasic.ByteToHexString(operateResult2.Content, ' '));
			}
			if (operateResult2.Content[5] != 48)
			{
				return new OperateResult<byte[]>(operateResult2.Content[5], FatekProgramOverTcp.GetErrorDescriptionFromCode((char)operateResult2.Content[5]));
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.FATEK.FatekProgramOverTcp.ReadBool(System.String,System.UInt16)" />
		public override OperateResult<bool[]> ReadBool(string address, ushort length)
		{
			OperateResult<byte[]> operateResult = FatekProgramOverTcp.BuildReadCommand(station, address, length, isBool: true);
			if (!operateResult.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult);
			}
			OperateResult<byte[]> operateResult2 = ReadBase(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return OperateResult.CreateFailedResult<bool[]>(operateResult2);
			}
			if (operateResult2.Content[0] != 2)
			{
				return new OperateResult<bool[]>(operateResult2.Content[0], "Read Faild:" + SoftBasic.ByteToHexString(operateResult2.Content, ' '));
			}
			if (operateResult2.Content[5] != 48)
			{
				return new OperateResult<bool[]>(operateResult2.Content[5], FatekProgramOverTcp.GetErrorDescriptionFromCode((char)operateResult2.Content[5]));
			}
			byte[] array = new byte[length];
			Array.Copy(operateResult2.Content, 6, array, 0, length);
			return OperateResult.CreateSuccessResult(array.Select((byte m) => m == 49).ToArray());
		}

		/// <inheritdoc cref="M:HslCommunication.Profinet.FATEK.FatekProgramOverTcp.Write(System.String,System.Boolean[])" />
		public override OperateResult Write(string address, bool[] value)
		{
			OperateResult<byte[]> operateResult = FatekProgramOverTcp.BuildWriteBoolCommand(station, address, value);
			if (!operateResult.IsSuccess)
			{
				return operateResult;
			}
			OperateResult<byte[]> operateResult2 = ReadBase(operateResult.Content);
			if (!operateResult2.IsSuccess)
			{
				return operateResult2;
			}
			if (operateResult2.Content[0] != 2)
			{
				return new OperateResult(operateResult2.Content[0], "Write Faild:" + SoftBasic.ByteToHexString(operateResult2.Content, ' '));
			}
			if (operateResult2.Content[5] != 48)
			{
				return new OperateResult<bool[]>(operateResult2.Content[5], FatekProgramOverTcp.GetErrorDescriptionFromCode((char)operateResult2.Content[5]));
			}
			return OperateResult.CreateSuccessResult();
		}

		/// <inheritdoc />
		public override string ToString()
		{
			return $"FatekProgram[{base.PortName}:{base.BaudRate}]";
		}
	}
}
